package com.xiao.mall.foundation.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.Map;

/**
 * @author wtl
 * @date 2021/9/9
 */
@Slf4j
public class UserAuthUtil {
    public static final String BLADE_AUTH = "Blade-Auth";
    public static final String AUTHORIZATION = "Authorization";
    public static final String USER_ID = "user_id";
    public static final String TST_UID = "tst_uid";
    private static String BEARER = "bearer";
    private static String BASIC = "basic";
    private static Integer AUTH_LENGTH = 7;
    private static Integer AUTHORIZATION_LENGTH = 6;
    private static String AUTHORIZATION_SIGN=":";


    /**
     * 获取当前登录用户Id
     * @return
     */
    public static Long getCurrentUserId() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes == null ? null : ((ServletRequestAttributes) requestAttributes).getRequest();
        if (request == null) {
            return null;
        }

        // 获取jwt token。
        String auth = request.getHeader(BLADE_AUTH);
        String token = getToken(auth);

        if (StringUtils.hasText(token)) {
            // 解析token。
            String[] words = token.split("\\.");
            if (words.length == 3) {
                String playload = words[1];

                // BASE64解析
                String playloadStr = new String(Base64.getUrlDecoder().decode(playload));
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Object> claimValueMap = null;
                try {
                    claimValueMap = objectMapper.readValue(playloadStr,
                            new TypeReference<Map<String, Object>>() {
                    });
                } catch (Exception e) {
                    log.error("解析用户信息失败,token: {}, 异常内容: {}", playload, e);
                    return null;
                }

                // 读取user-id。
                String userId = String.valueOf(claimValueMap.getOrDefault(USER_ID, null));
                if (StringUtils.hasText(userId)) {
                    return Long.parseLong(userId);
                }
            }
        }
        return null;
    }

    private static String getToken(String auth) {
        if (auth != null && auth.length() > AUTH_LENGTH) {
            String headStr = auth.substring(0, 6).toLowerCase();
            if (headStr.compareTo(BEARER) == 0) {
                auth = auth.substring(AUTH_LENGTH);
            }
            return auth;
        } else {
            return null;
        }
    }

    /**
     * 获取当前优惠卷渠道
     * @return
     */
    public static String getClientId() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes == null ? null : ((ServletRequestAttributes) requestAttributes).getRequest();
        if (request == null) {
            return null;
        }
        //获取数据
        String authorization = request.getHeader(AUTHORIZATION);

        //获取已经64加密之后的数据
        return  parseClientId(authorization);
//        //对base64进行解密
//        String baseDecrypt = new String(Base64.getUrlDecoder().decode(baseStr));
//        //截取AUTHORIZATION_SIGN符号之前的数据
//        String channel = baseDecrypt.substring(0, baseDecrypt.indexOf(AUTHORIZATION_SIGN));
        //判断该数据渠道是属于哪个渠道
//        if("app".equalsIgnoreCase(channel)){
//            return  PromotionChannel.App;
//        } else if("wechat".equalsIgnoreCase(channel)){
//            return  PromotionChannel.Wechat;
//        } else {
//            return  PromotionChannel.Room;
//        }
    }

    private static String parseClientId(String authorization) {
        if (authorization != null && authorization.length() > AUTHORIZATION_LENGTH) {
            String headStr = authorization.substring(0, 5).toLowerCase();
            if (headStr.compareTo(BASIC) == 0) {
                authorization = authorization.substring(AUTHORIZATION_LENGTH);
            }

            //对base64进行解密
            String baseDecrypt = new String(Base64.getUrlDecoder().decode(authorization));
            //截取AUTHORIZATION_SIGN符号之前的数据
            String clientId = baseDecrypt.substring(0, baseDecrypt.indexOf(AUTHORIZATION_SIGN));

            return clientId;
        } else {
            return "";
        }
    }

    /**
     * 获取当前登录用户Id
     * @return
     */
    public static Long getCurrentTstUid() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes == null ? null : ((ServletRequestAttributes) requestAttributes).getRequest();
        if (request == null) {
            return null;
        }

        // 获取jwt token。
        String auth = request.getHeader(BLADE_AUTH);
        String token = getToken(auth);

        if (StringUtils.hasText(token)) {
            // 解析token。
            String[] words = token.split("\\.");
            if (words.length == 3) {
                String playload = words[1];

                // BASE64解析
                String playloadStr = new String(Base64.getUrlDecoder().decode(playload));
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Object> claimValueMap = null;
                try {
                    claimValueMap = objectMapper.readValue(playloadStr,
                            new TypeReference<Map<String, Object>>() {
                            });
                } catch (Exception e) {
                    log.error("解析用户信息失败,token: {}, 异常内容: {}", playload, e);
                    return null;
                }

                // 读取user-id。
                String tstUid = String.valueOf(claimValueMap.getOrDefault(TST_UID, null));
                if (StringUtils.hasText(tstUid)) {
                    return Long.parseLong(tstUid);
                }
            }
        }
        return null;
    }
}
